if (!window["vg"]) {
    vg = {};
}

if (!vg.utility) {
    vg.utility = {};
}

vg.utility.Report = (function() {
    var mapXmlPrefix = "xmlLFButtonMap";
    var appXmlPrefix = "xmlLFButtonApplicationDefinition";
    var reportNamespaces = {
        'SOAP': 'http://schemas.xmlsoap.org/soap/envelope/',
        'REPORT': 'http://schemas.cordys.com/bsf/uc/webapps/1.0/report'
    };
    var xPaths = {
        "reportInput": "REPORTXML/REPORT:reportinput",
        "reportNode": "/SOAP:Envelope/SOAP:Body/REPORT:RunReport/REPORT:REPORT",
        "historyId": ".//*[local-name() = 'HISTORYID']"
    };
    var assertionCookie = "SAMLart";
    var previewReportXml = "<SOAP:Envelope xmlns:SOAP='http://schemas.xmlsoap.org/soap/envelope/'><SOAP:Body><RunReport xmlns='http://schemas.cordys.com/bsf/uc/webapps/1.0/report'><REPORTTYPE>adhoc</REPORTTYPE><ISMODIFIED>n</ISMODIFIED><REPORT></REPORT></RunReport></SOAP:Body></SOAP:Envelope>";
    var bdiIdPrefix = "bdi";
    var bdiLibrary = "wcp.library.data.BusDataIsland";
    var reportGateway = location.protocol + "//" + location.host + "/olc/com.cordys.uc.gateway.ReportDownloader.wcp?id=";

    /**
     * Creates a new bus data island with the id provided
     * @param  {String} id
     * @return {Object}
     */

    function getBusDataIsland(id) {
        var bdiDiv = document.createElement("div");
        bdiDiv.async = true;
        bdiDiv.id = id;
        application.addType(bdiDiv, bdiLibrary);
        document.body.appendChild(bdiDiv);
        return window[id] || bdiDiv;
    }

    /**
     * To get the report request. Uses CPF function runReport in xformscripts.js
     * @param {Object} btnId
     */

    function getReportRequest(btnId) {
        var mapXml = document.getElementById(mapXmlPrefix + btnId);
        var appXml = document.getElementById(appXmlPrefix + btnId);
        mapXml = mapXml.XMLDocument;
        appXml = cordys.cloneXMLDocument(appXml.XMLDocument);
        resolveFormInput(cordys.selectXMLNode(appXml, xPaths.reportInput, reportNamespaces), mapXml);
        var previewReportRequest = cordys.loadXMLDocument(previewReportXml);
        cordys.appendXMLNode(appXml.documentElement, cordys.selectXMLNode(previewReportRequest, xPaths.reportNode, reportNamespaces));
        return previewReportRequest;
    }

    function getResponseHandler() {
        var that = this;
        return function(eventObject) {
            that.fileURL = reportGateway + cordys.getTextContent(cordys.selectXMLNode(application.event.response, xPaths["historyId"]));
            downloadReport(that.fileURL + "&" + assertionCookie + "=" + getCookie(assertionCookie), that);
        };
    }

    var getCookie = function(check_name) {
        var a_all_cookies = document.cookie.split(";");
        var a_temp_cookie = '';
        var cookie_name = '';
        var cookie_value = '';
        var b_cookie_found = false;

        for (i = 0; i < a_all_cookies.length; i++) {
            // split the name-value pairs
            a_temp_cookie = a_all_cookies[i].split('=');
            // and trim left/right whitespace while we're at it
            cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');

            // if the extracted name matches passed check_name
            if (cookie_name == check_name) {
                b_cookie_found = true;
                // we need to handle case where cookie has no value but exists (no = sign, that is):
                if (a_temp_cookie.length > 1) {
                    cookie_value = unescape(a_temp_cookie[1].replace(/^\s+|\s+$/g, ''));
                }
                // note that in cases where cookie is initialized but no value, null is returned
                return cookie_value;
                break;
            }
            a_temp_cookie = null;
            cookie_name = '';
        }
        if (!b_cookie_found) {
            return null;
        }
    }

    function downloadReport(fileURL, that) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', fileURL, true);
        xhr.responseType = 'arraybuffer';
        xhr.onload = function(e) {
            if (this.status == 200) {
                var base64encoded = arrayBufferToBase64(this.response);
                that.base64Content = "data:application/pdf;base64," + base64encoded;
                that.responseCallback && that.responseCallback({
                    "base64Content": that.base64Content,
                    "url": that.fileURL
                });
            }
        };
        xhr.send();
    }

    function arrayBufferToBase64(buffer) {
        var binary = "";
        var bytes = new Uint8Array(buffer);
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return btoa(binary);
    }


    /**************************************** Report Class ******************************************************/

    function report(btnId, responseCallback, contentType) {
        this.bdi = getBusDataIsland(bdiIdPrefix + btnId);
        this.btnId = btnId;
        this.reportRequest = cordys.cloneXMLDocument(getReportRequest(btnId));
		this.responseCallback = responseCallback;
        this.bdi.onresponse = getResponseHandler.call(this, contentType);
        //parameters set after running the report
        this.base64Content = null;
        this.fileURL = null;
    }

    report.prototype = (function() {
        /**
         * To set the input parameters for the report.
         * @param {Object} inputObj - Object with the property names as the parameter names of inputs as defined
         * in iReport and the corresponding parameter values
         */
        var setInput = function(inputObj) {
            for (var i in inputObj) {
                var node = cordys.selectXMLNode(this.reportRequest, ".//*[@parameterName = '" + i + "']");
                cordys.setTextContent(node, inputObj[i]);
            }
        };

        /**
         * To generate the report and display it in the frame mentioned
         */
        var reset = function() {
            this.bdi.clear();
            this.bdi.request = getReportRequest(this.btnId);
            this.bdi.reset();
        };


        /**
         * Returns the base 64 content of the report file based on its
         */
        var getFileContent = function() {
            return this.base64Content;
        };

        return {
            "setInput": setInput,
            "reset": reset,
            "getFileContent": getFileContent
        };
    })();

    return report;
})();

scriptCallback && scriptCallback("Download IReport");